package ru.spbu.math.android.cbrf.dataprovider;

import ru.spbu.math.android.cbrf.model.RateType;
import ru.spbu.math.android.cbrf.model.StockItem;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * @author  Helga
 */
public class Validator {

    private IProvider cbrfProvider;
    private IProvider yandexProvider;
    
    private HashMap<RateType, IProvider> rateTypeMap;
    
    private static final String[] cbrfCurrencySource = {"GBP", "BYR", "EUR", "USD", "DKK", "ISK", "CAD", "CNY", "NOK", "XDR", "SGD", "TRY", "UAH", "SEK", "CHF", "JPY", "AUD"};
    private static final String[] cbrfMetalSource = {"AUR", "ARG", "PT", "PD"};
    private static final String[] yandexOilSource = {"brent"};
    private static final String[] yandexMetalSource = {"AL", "CU", "NI", "SN", "PD", "PT", "AG", "ZN"};
    
    private static List<RateType> currencyRateTypes;
    private static List<RateType> metalRateTypes;
    private static List<RateType> oilRateTypes;
    
    private static final String RUB = "RUB";
    private static final String USD = "USD";

    public boolean validate(StockItem source, StockItem target) {

    	if (source == null || target == null) {
    		return false;
    	}
    	
    	if (source.getCode() == null || target.getCode() == null) {
    		return false;
    	}
    	
    	RateType rt = new RateType(source.getCode(), target.getCode());
    	
    	
        return rateTypeMap.containsKey(rt);
    }
    
    //by Nikita Bumakov
    private static boolean isCurrency(String source, String target){
    	RateType rt = new RateType(source, target);
    	return currencyRateTypes.contains(rt);
    }
    
    //by Nikita Bumakov
    private static boolean isMetal(String source, String target){
    	RateType rt = new RateType(source, target);
    	return currencyRateTypes.contains(rt);
    }
    
    //by Nikita Bumakov
    private static boolean isOil(String source, String target){
    	RateType rt = new RateType(source, target);
    	return currencyRateTypes.contains(rt);
    }
    
  //by Nikita Bumakov
    public static DataProvider.RateTypeGroups getRateTypeGroupsbySourceTarget(String source, String target){
    	if (isCurrency(source, target)) return DataProvider.RateTypeGroups.Currency;
      	if (isMetal(source, target)) return DataProvider.RateTypeGroups.Metal;
      	if (isOil(source, target)) return DataProvider.RateTypeGroups.Oil;
    	return null;
    }

    public IProvider getProvider(StockItem source, StockItem target) {

        RateType rt = new RateType(source.getCode(), target.getCode());
        return rateTypeMap.get(rt);
    }

    public List<RateType> getRateTypes(DataProvider.RateTypeGroups category) {

        if (category.equals(DataProvider.RateTypeGroups.Currency)) {

            return currencyRateTypes;

        } else if (category.equals(DataProvider.RateTypeGroups.Metal)) {

            return metalRateTypes;

        } else if (category.equals(DataProvider.RateTypeGroups.Oil)) {

            return oilRateTypes;

        }

        return null;
    }

    public Validator() {

        cbrfProvider = new CbrfData();
        yandexProvider = new YandexProvider();

        currencyRateTypes = new ArrayList<RateType>();
        metalRateTypes = new ArrayList<RateType>();
        oilRateTypes = new ArrayList<RateType>();

        rateTypeMap = createRateTypeMap();
    }

    private HashMap<RateType, IProvider> createRateTypeMap() {
        // hard code :'(

        HashMap<RateType, IProvider> map = new HashMap<RateType, IProvider>();

        /*
         * from CBRF
         * category DataProvider.RateTypeGroups.Currency
         * target RUB
         */
        for (int i = 0; i < cbrfCurrencySource.length; i++) {
            RateType rateType = new RateType(cbrfCurrencySource[i], RUB);
            map.put(rateType, cbrfProvider);
            currencyRateTypes.add(rateType);
        }

        /*
        * from CBRF
        * category DataProvider.RateTypeGroups.Metal
        * target RUB
        */
        for (int i = 0; i < cbrfMetalSource.length; i++) {
            RateType rateType = new RateType(cbrfMetalSource[i], RUB);
            map.put(rateType, cbrfProvider);
            metalRateTypes.add(rateType);
        }

        /*
        * from Yandex
        * category DataProvider.RateTypeGroups.Oil
        * target USD
        */
        for (int i = 0; i < yandexOilSource.length; i++) {
            RateType rateType = new RateType(yandexOilSource[i], USD);
            map.put(rateType, yandexProvider);
            oilRateTypes.add(rateType);
        }
        
        /*
         * from Yandex
         * category DataProvider.RateTypeGroups.metal
         * target USD
         */
         for (int i = 0; i < yandexMetalSource.length; i++) {
             RateType rateType = new RateType(yandexMetalSource[i], USD);
             //RateTypeInformation rtInfo = new RateTypeInformation(yandexProvider, DataProvider.RateTypeGroups.Oil);
             map.put(rateType, yandexProvider);
             metalRateTypes.add(rateType);
         }    
         
         Collections.sort(currencyRateTypes, RateType.getComparator());
         Collections.sort(oilRateTypes, RateType.getComparator());
         Collections.sort(metalRateTypes, RateType.getComparator());

        return map;
    }

}
